package com.paishen.common.widget;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.paishen.common.util.BaseUtil;
import com.paishen.common.R;

import java.util.Stack;

public class TitleLayout extends FrameLayout {

    private static final boolean DEBUG = false;
    private FrameLayout background;
    private View line;

    private final Stack<TitleContainer> titleContainers = new Stack<TitleContainer>();

    public TitleLayout(Context context) {
        this(context, null);
    }

    public TitleLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        background = new FrameLayout(context);
        background.setLayoutParams(new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                (int) getResources().getDimension(R.dimen.title_height) + (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? BaseUtil.getStatusBarHeight() : 0)));
        background.setBackgroundColor(DEBUG ? 0x66CCCCCC : 0xFFFFFFFF);
        addView(background);

        line = new View(context);
        FrameLayout.LayoutParams lpLine = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1);
        lpLine.gravity = Gravity.BOTTOM;
        line.setLayoutParams(lpLine);
        line.setBackgroundColor(0xFFB3B3B3);
        addView(line);

        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // interrupt click event
            }
        });

        // 默认使用状态栏[黑色风格]
        boolean resultMode = BaseUtil.setStatusBarDarkMode(true, (Activity) context);
        if (!resultMode) {
            View top = new View(context);
            top.setBackgroundColor(0xFF05131A);
            top.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, BaseUtil.getStatusBarHeight()));
            background.addView(top);
        }
    }


    public void setLineVisibility(int visibility) {
        line.setVisibility(visibility);
    }

    @Override
    public void setBackgroundColor(int color) {
        background.setBackgroundColor(color);
        background.invalidate();
    }

    public void setCurrContentCenterAlpha(final float alpha) {
        if (!titleContainers.isEmpty()) {
            final TitleContainer curr = titleContainers.peek();
            if (curr != null) {
                curr.layCenter.setAlpha(alpha);
            }
        }
    }


    public TitleContainer pushContent(View left, String titleText, View right, boolean anim) {
        return pushContent(left, titleText, right, anim, 1f);
    }

    public TitleContainer pushContent(View left, String titleText, View right, boolean anim, float alpha) {
        return pushContent(left, makeTextTitle(titleText), right, anim, alpha);
    }

    public TitleContainer pushContent(View left, View center, View right, boolean anim) {
        return pushContent(left, center, right, anim, 1f);
    }

    /**
     * replace stack top
     */
    public TitleContainer pushContent(View left, View center, View right, boolean anim, float alpha) {
        final TitleContainer tc = new TitleContainer(getContext());
        tc.setContent(left, center, right);
        tc.setCurrAlpha(alpha);
        TitleContainer last = null;
        if (!titleContainers.isEmpty()) {
            last = titleContainers.pop();
        }
        titleContainers.push(tc);
        addView(tc);
        background.setAlpha(alpha);
        line.setAlpha(alpha);

        final TitleContainer mLast = last;
        if (anim) {
            tc.setEnabled(false);
            if (mLast != null) last.setEnabled(false);
            ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(300);
            animator.addUpdateListener(new AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float value = (Float) animation.getAnimatedValue();
                    if (mLast != null) {
                        mLast.layLeft.setAlpha(1 - value);
                        mLast.layCenter.setAlpha(1 - value);
                        mLast.layCenter.setTranslationX(-getWidth() / 6 * value);
                        mLast.layRight.setAlpha(1 - value);
                    }
                    tc.layLeft.setAlpha(value);
                    tc.layCenter.setAlpha(value);
                    tc.layCenter.setTranslationX(getWidth() / 6 * (1 - value));
                    tc.layRight.setAlpha(value);
                }
            });
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    tc.setEnabled(true);
                    if (mLast != null) {
                        mLast.setEnabled(true);
                        removeView(mLast);
                    }
                }
            });
            animator.start();
        } else {
            removeView(mLast);
        }

        return tc;
    }

    public TitleContainer pushNewContent(View left, String titleText, View right, boolean anim) {
        return pushNewContent(left, titleText, right, anim, 1f);
    }

    public TitleContainer pushNewContent(View left, String titleText, View right, boolean anim, float alpha) {
        return pushNewContent(left, makeTextTitle(titleText), right, anim, alpha);
    }

    public TitleContainer pushNewContent(View left, View center, View right, boolean anim) {
        return pushNewContent(left, center, right, anim, 1f);
    }

    public TitleContainer pushNewContent(View left, View center, View right, boolean anim, float alpha) {
        final TitleContainer tc = new TitleContainer(getContext());
        tc.setContent(left, center, right);
        tc.setCurrAlpha(alpha);

        TitleContainer last = null;
        if (!titleContainers.isEmpty()) {
            last = titleContainers.peek();
        }

        final TitleContainer mLast = last;
        titleContainers.push(tc);
        addView(tc);

        background.setAlpha(alpha);
        line.setAlpha(alpha);
        final float currBackgroundAlpha = background.getAlpha();
        final float currLineAlpha = line.getAlpha();

        if (anim) {
            tc.setEnabled(false);
            if (last != null) last.setEnabled(false);
            ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(300);
            animator.addUpdateListener(new AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float value = (Float) animation.getAnimatedValue();
                    if (mLast != null) {
                        mLast.layLeft.setAlpha(1 - value);
                        mLast.layCenter.setAlpha(1 - value);
                        mLast.layCenter.setTranslationX(-getWidth() / 6 * value);
                        mLast.layRight.setAlpha(1 - value);
                    }
                    tc.layLeft.setAlpha(value);
                    tc.layCenter.setAlpha(value);
                    tc.layCenter.setTranslationX(getWidth() / 6 * (1 - value));
                    tc.layRight.setAlpha(value);

                    background.setAlpha(mLast.a + (currBackgroundAlpha - mLast.a) * value);
                    line.setAlpha(mLast.a + (currLineAlpha - mLast.a) * value);
                }
            });
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    tc.setEnabled(true);
                    if (mLast != null) {
                        mLast.setEnabled(true);
                        mLast.setVisibility(View.GONE);
                    }

                }
            });
            animator.start();
        } else {
            last.setVisibility(View.GONE);
            final float value = 1;
            last.layLeft.setAlpha(1 - value);
            last.layCenter.setAlpha(1 - value);
            last.layCenter.setTranslationX(-getWidth() / 6 * value);
            last.layRight.setAlpha(1 - value);
        }

        return tc;
    }

    public View popToLastContent() {
        return popToLastContent(true);
    }

    /**
     * 返回上一页
     *
     * @param anim 是否以动画的方式移动
     * @return
     */
    public View popToLastContent(boolean anim) {
        if (titleContainers.size() < 2) {
            // Not enough item
            return null;
        }
        final TitleContainer curr = titleContainers.pop();
        final float currLayLeftAlpha = curr.layLeft.getAlpha();
        final float currLayCenterAlpha = curr.layCenter.getAlpha();
        final float currLayCenterTranslateX = curr.layCenter.getTranslationX();
        final float currLayRightAlpha = curr.layRight.getAlpha();
        final TitleContainer last = titleContainers.peek();
        final float lastLayLeftAlpha = last.layLeft.getAlpha();
        final float lastLayCenterAlpha = last.layCenter.getAlpha();
        final float lastLayCenterTranslateX = last.layCenter.getTranslationX();
        final float lastLayRightAlpha = last.layRight.getAlpha();

        final float currBackgroundAlpha = background.getAlpha();
        final float currLineAlpha = line.getAlpha();


        if (anim) {
            curr.setEnabled(false);
            last.setEnabled(false);
            ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(300);
            animator.addUpdateListener(new AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float value = (Float) animation.getAnimatedValue();
                    curr.layLeft.setAlpha(currLayLeftAlpha * (1 - value));
                    curr.layCenter.setAlpha(currLayCenterAlpha * (1 - value));
                    curr.layCenter
                            .setTranslationX(currLayCenterTranslateX + (getWidth() / 6 - currLayCenterTranslateX) * value);
                    curr.layRight.setAlpha(currLayRightAlpha * (1 - value));

                    last.layLeft.setAlpha(lastLayLeftAlpha + (1 - lastLayLeftAlpha) * value);
                    last.layCenter.setAlpha(lastLayCenterAlpha + (1 - lastLayLeftAlpha) * value);
                    last.layCenter.setTranslationX(lastLayCenterTranslateX * (1 - value));
                    last.layRight.setAlpha(lastLayRightAlpha + (1 - lastLayRightAlpha) * value);

                    background.setAlpha(currBackgroundAlpha + (last.a - currBackgroundAlpha) * value);
                    line.setAlpha(currLineAlpha + (last.a - currLineAlpha) * value);
                }
            });
            animator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    curr.setEnabled(true);
                    last.setEnabled(true);
                    removeView(curr);
                }
            });
            animator.start();
            last.setVisibility(View.VISIBLE);
        } else {
            removeView(curr);
            last.setVisibility(View.VISIBLE);
        }

        return last;
    }

    public void returnToCurrentContent() {
        if (titleContainers.size() < 2) {
            // Not enough item
            return;
        }

        final TitleContainer curr = titleContainers.get(titleContainers.size() - 1);
        final float currLayLeftAlpha = curr.layLeft.getAlpha();
        final float currLayCenterAlpha = curr.layCenter.getAlpha();
        final float currLayCenterTranslateX = curr.layCenter.getTranslationX();
        final float currLayRightAlpha = curr.layRight.getAlpha();
        final TitleContainer last = titleContainers.get(titleContainers.size() - 2);
        final float lastLayLeftAlpha = last.layLeft.getAlpha();
        final float lastLayCenterAlpha = last.layCenter.getAlpha();
        final float lastLayCenterTranslateX = last.layCenter.getTranslationX();
        final float lastLayRightAlpha = last.layRight.getAlpha();

        final float currBackgroundAlpha = background.getAlpha();
        final float currLineAlpha = line.getAlpha();

        ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(300);
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (Float) animation.getAnimatedValue();

                curr.layLeft.setAlpha(currLayLeftAlpha + (1 - currLayLeftAlpha) * value);
                curr.layCenter.setAlpha(currLayCenterAlpha + (1 - currLayCenterAlpha) * value);
                curr.layCenter.setTranslationX(currLayCenterTranslateX * (1 - value));
                curr.layRight.setAlpha(currLayRightAlpha + (1 - currLayRightAlpha) * value);

                last.layLeft.setAlpha(lastLayLeftAlpha * (1 - value));
                last.layCenter.setAlpha(lastLayCenterAlpha * (1 - value));
                last.layCenter.setTranslationX(lastLayCenterTranslateX + (-getWidth() / 6 - lastLayCenterTranslateX) * value);
                last.layRight.setAlpha(lastLayRightAlpha * (1 - value));

                background.setAlpha(currBackgroundAlpha + (curr.a - currBackgroundAlpha) * value);
                line.setAlpha(currLineAlpha + (curr.a - currLineAlpha) * value);
            }
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                titleContainers.get(titleContainers.size() - 2).setVisibility(View.GONE);
            }
        });
        animator.start();
    }

    public void setToLastAnimationProgress(float progress) {
        if (titleContainers.size() < 2) {
            // Not enough item
            return;
        }

        final TitleContainer curr = titleContainers.get(titleContainers.size() - 1);
        final TitleContainer last = titleContainers.get(titleContainers.size() - 2);
        last.setVisibility(View.VISIBLE);

        float value = progress;
        curr.layLeft.setAlpha(1 - value);
        curr.layCenter.setAlpha(1 - value);
        curr.layCenter.setTranslationX(getWidth() / 6 * value);
        curr.layRight.setAlpha(1 - value);

        last.layLeft.setAlpha(value);
        last.layCenter.setAlpha(value);
        last.layCenter.setTranslationX(-getWidth() / 6 * (1 - value));
        last.layRight.setAlpha(value);


        background.setAlpha(curr.a - (curr.a - last.a) * value);
        line.setAlpha(curr.a - (curr.a - last.a) * value);
    }

    private View makeTextTitle(String text) {
        TextView txTitle = new TextView(getContext());
        LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lp.gravity = Gravity.CENTER;
        txTitle.setLayoutParams(lp);
        txTitle.setTextSize(17);
        txTitle.setGravity(Gravity.CENTER);
        txTitle.setText(text);
        txTitle.setTextColor(0xFF05131A);
        return txTitle;
    }

    static class TitleContainer extends LinearLayout {
        private float a = 1f;
        private final LinearLayout layCenter, layLeft, layRight;

        public void setEnabled(boolean enabled) {
            for (int i = 0; i < layCenter.getChildCount(); i++) {
                layCenter.getChildAt(i).setEnabled(enabled);
            }
            for (int i = 0; i < layLeft.getChildCount(); i++) {
                layLeft.getChildAt(i).setEnabled(enabled);
            }
            for (int i = 0; i < layRight.getChildCount(); i++) {
                layRight.getChildAt(i).setEnabled(enabled);
            }
        }

        public TitleContainer(Context context) {
            super(context);

            setOrientation(LinearLayout.HORIZONTAL);
            int fitHeight = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT ? BaseUtil.getStatusBarHeight() : 0;
            int titleHeight = (int) getResources().getDimension(R.dimen.title_height);
            LinearLayout.LayoutParams lpLeft = new LinearLayout.LayoutParams(0, fitHeight + titleHeight);

            lpLeft.weight = 1;
            layLeft = new LinearLayout(context);
            layLeft.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
            layLeft.setLayoutParams(lpLeft);
            layLeft.setPadding(0, fitHeight, 0, 0);
            if (DEBUG) layLeft.setBackgroundColor(0x66cc11ff);
            addView(layLeft);
            layCenter = new LinearLayout(context);

            LinearLayout.LayoutParams lpCenter = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, fitHeight + titleHeight);
            layCenter.setLayoutParams(lpCenter);
            layCenter.setGravity(Gravity.CENTER);
            layCenter.setPadding(0, fitHeight, 0, 0);
            addView(layCenter);
            LinearLayout.LayoutParams lpRight = new LinearLayout.LayoutParams(0, fitHeight + titleHeight);
            lpRight.weight = 1;
            layRight = new LinearLayout(context);
            layRight.setGravity(Gravity.CENTER_VERTICAL | Gravity.RIGHT);
            layRight.setLayoutParams(lpRight);
            layRight.setPadding(0, fitHeight, 0, 0);
            if (DEBUG) layRight.setBackgroundColor(0x66ffcc11);
            addView(layRight);
        }

        public void setContent(View left, View center, View right) {
            LinearLayout.LayoutParams lpTitleMenu = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);

            if (left != null && DEBUG) left.setBackgroundColor(0x66445566);
            if (center != null && DEBUG) center.setBackgroundColor(0x66446655);
            if (right != null && DEBUG) right.setBackgroundColor(0x66664455);

            if (left != null) layLeft.addView(left, lpTitleMenu);
            if (center != null) layCenter.addView(center, lpTitleMenu);
            if (right != null) layRight.addView(right, lpTitleMenu);

        }

        public void setCurrAlpha(float alpha) {
            this.a = alpha;
        }
    }
}
